package com.tjbank.cssys.service.impl;

import com.alibaba.fastjson.JSON;
import com.tjbank.cssys.api.OrganService;
import com.tjbank.cssys.api.RelationIDService;
import com.tjbank.cssys.api.UserService;
import com.tjbank.cssys.dto.OrganDTO;
import com.tjbank.cssys.dto.UserDTO;
import com.tjbank.cssys.entityext.OrganNode;
import com.tjbank.cssys.framework.base.enums.YesOrNoEnum;
import com.tjbank.cssys.framework.base.exception.ServiceException;
import com.tjbank.cssys.framework.base.util.GeneratIDUtil;
import com.tjbank.cssys.mapperext.OrganMapper;
import com.tjbank.cssys.mapperext.UserMapper;
import com.tjbank.cssys.mybatis.IamGroupDao;
import com.tjbank.cssys.mybatis.entity.IamGroup;
import com.tjbank.cssys.mybatis.entity.IamGroupKey;
import com.tjbank.cssys.mybatis.mapper.IamGroupMapper;
import com.tjbank.cssys.mybatis.sqlbuilder.IamGroupSqlBuilder;
import com.tjbank.cssys.service.convert.OrganConvert;
import com.tjbank.cssys.service.convert.UserConvert;
import com.tjbank.cssys.service.enums.EntityTypeEnum;
import com.tjbank.cssys.service.util.Const;
import com.tjbank.cssys.service.util.ForestNodeMerger;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 机构管理
 * <p>
 * Package : com.tansun.magicube.iam.service.impl
 *
 * @author -- lijiangtao 2020年7月13日 上午10:50:12
 */
@Service
public class OrganServiceImpl implements OrganService {
    protected static final Logger logger = LoggerFactory.getLogger(OrganServiceImpl.class);
    @Autowired
    private IamGroupDao organDao;

    @Autowired
    private OrganMapper organMapper;

    @Autowired
    private UserService userService;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RelationIDService relationIDService;

    @Autowired
    private IamGroupMapper iamGroupMapper;

    /**
     * 新增机构
     *
     * @param organDTO
     * @return
     * @author -- lijiangtao 2020年7月21日 下午5:13:09
     */
    @Override
    @Transactional
    public Object addOrgan(OrganDTO organDTO) {
        OrganDTO organParent = this.updateTreeByParentId(organDTO.getParentId());
        IamGroup entity = OrganConvert.INSTANCE.dtoToEntity(organDTO);
        this.setOrganization(organParent, entity);
        int insert = organDao.insert(entity);

        return entity;
    }

    /**
     * 根据 parentId 更新 Tree
     *
     * @param parentId
     * @return
     * @author -- lijiangtao 2020年5月29日 下午8:40:07
     */
    private OrganDTO updateTreeByParentId(String parentId) {
        IamGroupSqlBuilder sqlBuilder = new IamGroupSqlBuilder();
        sqlBuilder.andIdEqualTo(parentId).andIsDeletedEqualTo(YesOrNoEnum.NO.getCode());
        IamGroup entity = organDao.selectBySqlBuilder(sqlBuilder);
        OrganNode node = OrganConvert.INSTANCE.entityToNode(entity);
        organMapper.updateLNode(node);
        organMapper.updateRNode(node);
        return OrganConvert.INSTANCE.entityToDTO(entity);
    }

    /**
     * setOrganization
     *
     * @param organizationParent
     * @param entity
     * @author -- lijiangtao 2020年7月14日 下午2:57:54
     */
    private void setOrganization(OrganDTO organParent, IamGroup entity) {
        entity.setId(GeneratIDUtil.getUUId());
        entity.setCreateTime(new Date());
        entity.setLft(organParent.getRgt());
        entity.setRgt(organParent.getRgt() + 1);
        entity.setType(EntityTypeEnum.ORGAN_TYPE.getCode());
        entity.setState(YesOrNoEnum.YES.getCode());
        entity.setCreateTime(new Date());
        entity.setUpdateTime(new Date());
    }

    /**
     * 删除机构
     *
     * @param nodeId
     * @return
     * @author -- lijiangtao 2020年7月21日 下午5:14:16
     */
    @Override
    @Transactional
    public Integer deleteOrgan(String nodeId) {
        this.checkNodeId(nodeId);
        this.checkUserByOrganId(nodeId);
        OrganNode node = OrganConvert.INSTANCE.entityToNode(organDao.selectByPrimaryKey(new IamGroupKey(nodeId)));
        List<IamGroup> list = organMapper.queryAllChildNode(node);
        node.setNum(list.size() * 2);
        organMapper.deleteLNode(node);
        organMapper.deleteRNode(node);
        List<Integer> resultList = new ArrayList<Integer>();
        list.forEach(e -> resultList.add(organDao.deleteByPrimaryKey(new IamGroupKey(e.getId()))));
        return resultList.size();
    }

    /**
     * 查询机构信息list-->tree
     *
     * @param organDTO
     * @return
     * @author -- lijiangtao 2020年7月22日 上午9:51:44
     */
    @Override
    public List<OrganDTO> organTreeList(OrganDTO organDTO) {
        List<OrganDTO> list = new ArrayList<OrganDTO>();
        // 系统租户+超级管理员
        if (Objects.deepEquals(organDTO.getTenantCode(), Const.ROOT_TENANT_CODE) && Objects.deepEquals(organDTO.getLoginCode(), Const.ROOT_USER_CODE)) {
            list = OrganConvert.INSTANCE.entitiesToDTOList(organDao.selectListBySqlBuilder(this.setRootSqlBuilder(organDTO)));
        } else {
            // 获取登录用户的数据权限
            //  List<String> roleIdList = relationIDService.queryRoleIdListByUserId(userService.getUser(organDTO.getTenantCode(), organDTO.getLoginCode()).getId());
            list = relationIDService.queryDataPermByRoleId(null, organDTO);
        }
        return ForestNodeMerger.merge(list);
    }

    /**
     * setRootSqlBuilder
     *
     * @return
     * @author -- lijiangtao 2020年7月17日 下午2:04:11
     */
    private IamGroupSqlBuilder setRootSqlBuilder(OrganDTO organDTO) {
        if (StringUtils.isEmpty(organDTO.getLoginCode())) {
            throw new ServiceException("登录账号不能为空");
        }
        if (StringUtils.isBlank(organDTO.getTenantCode())) {
            throw new ServiceException("租户代码不能为空");
        }
        IamGroupSqlBuilder sqlBuilder = new IamGroupSqlBuilder();
        sqlBuilder.or(new IamGroupSqlBuilder().orTypeEqualTo(EntityTypeEnum.ORGAN_TYPE.getCode()).orTypeEqualTo(EntityTypeEnum.TENANT_TYPE.getCode()));
        // 机构代码
        if (StringUtils.isNotBlank(organDTO.getCode())) {
            sqlBuilder.andCodeLikeBoth(organDTO.getCode());
        }
        // 机构名称
        if (StringUtils.isNotBlank(organDTO.getName())) {
            sqlBuilder.andNameLikeBoth(organDTO.getName());
        }
        sqlBuilder.andStateEqualTo(YesOrNoEnum.YES.getCode()).andIsDeletedEqualTo(YesOrNoEnum.NO.getCode()).orderByLft(false);
        return sqlBuilder;
    }

    /**
     * 角色授权 ----> 数据权限
     *
     * @param organDTO
     * @return
     * @author -- lijiangtao 2020年7月31日 下午12:48:22
     */
    @Override
    public List<OrganDTO> organOrgTreeByTenantCode(OrganDTO organDTO) {
        if (StringUtils.isEmpty(organDTO.getTenantCode())) {
            throw new ServiceException("租户代码不能为空");
        }
        IamGroupSqlBuilder sqlBuilder = new IamGroupSqlBuilder();
        sqlBuilder.or(new IamGroupSqlBuilder().orTypeEqualTo(EntityTypeEnum.ORGAN_TYPE.getCode()).orTypeEqualTo(EntityTypeEnum.TENANT_TYPE.getCode()));
        sqlBuilder.andTenantCodeEqualTo(organDTO.getTenantCode());
        sqlBuilder.andStateEqualTo(YesOrNoEnum.YES.getCode()).andIsDeletedEqualTo(YesOrNoEnum.NO.getCode()).orderByLft(false);
        return ForestNodeMerger.merge(OrganConvert.INSTANCE.entitiesToDTOList(organDao.selectListBySqlBuilder(sqlBuilder)));
    }

    /**
     * 更新机构
     *
     * @param organDTO
     * @return
     * @author -- lijiangtao 2020年7月24日 下午3:41:06
     */
    @Override
    @Transactional
    public Integer updateOrgan(OrganDTO organDTO) {
        this.checkNodeId(organDTO.getId());
        IamGroup entity = OrganConvert.INSTANCE.dtoToEntity(organDTO);
        entity.setUpdateTime(new Date());
        entity.setType(EntityTypeEnum.ORGAN_TYPE.getCode());
        IamGroupSqlBuilder sqlBuilder = new IamGroupSqlBuilder();
        sqlBuilder.andIdEqualTo(entity.getId());
        return organDao.updateBySqlBuilderSelective(entity, sqlBuilder);
    }

    /**
     * 根据租户Code分页查询机构信息
     *
     * @param organDTO
     * @param pageable
     * @return
     * @author -- lijiangtao 2020年7月26日 上午12:01:25
     */
    @Override
    @SuppressWarnings("all")
    public Page<OrganDTO> queryOrganByTenantCode(OrganDTO organDTO, Pageable pageable) {
        if (StringUtils.isEmpty(organDTO.getTenantCode())) {
            throw new ServiceException("tenantCode:租户代码不能为空");
        }
        IamGroupSqlBuilder sqlBuilder = new IamGroupSqlBuilder();
        sqlBuilder.setPageSize(pageable.getPageSize());
        sqlBuilder.setIndexNo((int) pageable.getOffset());
        sqlBuilder.andTypeEqualTo(EntityTypeEnum.ORGAN_TYPE.getCode()).andIsDeletedEqualTo(YesOrNoEnum.NO.getCode());
        sqlBuilder.andTenantCodeEqualTo(organDTO.getTenantCode()).orderByUpdateTime(true).setAutoFilterNull(true);
        return new PageImpl(OrganConvert.INSTANCE.entitiesToDTOList(organDao.selectListBySqlBuilder(sqlBuilder)), pageable, organDao.countBySqlBuilder(sqlBuilder));
    }

    /**
     * 校验节点ID
     *
     * @param nodeId
     * @author -- lijiangtao 2020年6月14日 上午12:37:48
     */
    private void checkNodeId(String nodeId) {
        if (StringUtils.isBlank(nodeId)) {
            throw new ServiceException("节点ID不能为空");
        }
    }

    /**
     * 校验该机构下是否存在用户
     *
     * @param nodeId
     * @author -- lijiangtao 2020年7月14日 下午4:14:06
     */
    private void checkUserByOrganId(String nodeId) {
        List<UserDTO> userList = userService.queryUserByOrganId(nodeId);
        if (!userList.isEmpty()) {
            throw new ServiceException("该机构下存在用户!");
        }
    }

    /**
     * 根据机构节点分页查询用户信息
     *
     * @param nodeId
     * @param pageable
     * @return
     * @author -- lijiangtao 2020年7月27日 下午5:58:12
     */
    @Override
    @SuppressWarnings("all")
    public Map<String,Object> queryUserByNodeId(String nodeId, Pageable pageable) {
        logger.info("----根据机构查询用户----start---nodeId:"+nodeId);
        String level = null;
        if (nodeId.equals("0000_root_tenant_no_delete")) {
            level = "1";
        } else {
            Map<String, String> result = userMapper.getParentId(nodeId);
            String parentId = result.get("PARENT_ID");
            if (parentId.equals("0000_root_tenant_no_delete")) {
                level = "1";
            } else {
                level = "2";
            }
        }
        Map<String,Object> resultMap=new HashMap<>();
        OrganNode node = OrganConvert.INSTANCE.entityToNode(organDao.selectByPrimaryKey(new IamGroupKey(nodeId)));
        node.setPageSize(pageable.getPageSize()).setIndexNo((int) pageable.getOffset());
        Page<UserDTO> page = new PageImpl(UserConvert.INSTANCE.entitiesToDtoList(userMapper.queryUserByOrgIdList(node)), pageable, userMapper.countUser(node));
        resultMap.put("page",page);
        resultMap.put("level",level);
        logger.info("----根据机构查询用户----end---"+JSON.toJSONString(resultMap));
        return resultMap;
    }


    @Override
    public Map<String, String> getCountByCodeOrName(Map<String, String> map) {
        Map<String, String> mapResult = new HashMap<>();
        int result = iamGroupMapper.getCodeOrName(map);
        if (result == 0) {
            mapResult.put("code", "200");
            mapResult.put("message", "不重复");
        } else {
            mapResult.put("code", "201");
            mapResult.put("message", "重复");
        }
        return mapResult;
    }
}
